﻿/*
 
Celerity: Sensory Overload
Copright 2012 by Adam Hill, David Gannon, Thomas Tamblyn & Patrick Ytting
Contact: adam.hill@outlook.com
Website: adamhill.org
Licence: MS-Pl Licence
  
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Celerity.World
{
	public class Cube
	{
		public VertexPositionColorTexture[] vertices;
		public short[] indices;
		public Vector4 colour;
		public Vector3 Centre
		{
			get
			{
				Vector3 value = Vector3.Zero;
				foreach (VertexPositionColorTexture vpct in vertices)
					value += vpct.Position;
				return value / (float)vertices.Count();
			}
		}
		public bool zUnset;
		
		public Cube(float cellSize, Vector4 colour)
		{
			this.colour = colour;
			this.CreateVertices(cellSize);
			this.CreateIndices();
			this.BuildUV();
			//this.centre = new Vector3(0.0f, 0.0f, 0.0f);
			this.zUnset = true;
		}

		private void CreateVertices(float cellSize)
		{
			this.vertices = new VertexPositionColorTexture[24];
			float halfSize = cellSize / 2.0f;

			//front face
			this.vertices[0].Position = new Vector3(-halfSize, -halfSize, halfSize);
			this.vertices[1].Position = new Vector3(-halfSize, halfSize, halfSize);
			this.vertices[2].Position = new Vector3(halfSize, halfSize, halfSize);
			this.vertices[3].Position = new Vector3(halfSize, -halfSize, halfSize);
			
			//back face
			this.vertices[4].Position = new Vector3(-halfSize, halfSize, -halfSize);
			this.vertices[5].Position = new Vector3(-halfSize, -halfSize, -halfSize);
			this.vertices[6].Position = new Vector3(halfSize, -halfSize, -halfSize);
			this.vertices[7].Position = new Vector3(halfSize, halfSize, -halfSize);

			//left face
			this.vertices[8].Position = new Vector3(halfSize, halfSize, -halfSize);
			this.vertices[9].Position = new Vector3(halfSize, -halfSize, -halfSize);
			this.vertices[10].Position = new Vector3(halfSize, -halfSize, halfSize);
			this.vertices[11].Position = new Vector3(halfSize, halfSize, halfSize);

			//right face
			this.vertices[12].Position = new Vector3(-halfSize, halfSize, halfSize);
			this.vertices[13].Position = new Vector3(-halfSize, -halfSize, halfSize);
			this.vertices[14].Position = new Vector3(-halfSize, -halfSize, -halfSize);
			this.vertices[15].Position = new Vector3(-halfSize, halfSize, -halfSize);

			//top face
			this.vertices[16].Position = new Vector3(halfSize, halfSize, -halfSize);
			this.vertices[17].Position = new Vector3(halfSize, halfSize, halfSize);
			this.vertices[18].Position = new Vector3(-halfSize, halfSize, halfSize);
			this.vertices[19].Position = new Vector3(-halfSize, halfSize, -halfSize);

			//bottom face
			this.vertices[20].Position = new Vector3(-halfSize, -halfSize, -halfSize);
			this.vertices[21].Position = new Vector3(-halfSize, -halfSize, halfSize);
			this.vertices[22].Position = new Vector3(halfSize, -halfSize, halfSize);
			this.vertices[23].Position = new Vector3(halfSize, -halfSize, -halfSize);

		}

		private void CreateIndices()
		{
			this.indices = new short[36];
			this.indices[0] = 0;
			this.indices[1] = 1;
			this.indices[2] = 2;
			this.indices[3] = 0;
			this.indices[4] = 2;
			this.indices[5] = 3;

			this.indices[6] = 4;
			this.indices[7] = 5;
			this.indices[8] = 6;
			this.indices[9] = 4;
			this.indices[10] = 6;
			this.indices[11] = 7;

			this.indices[12] = 8;
			this.indices[13] = 9;
			this.indices[14] = 10;
			this.indices[15] = 8;
			this.indices[16] = 10;
			this.indices[17] = 11;

			this.indices[18] = 12;
			this.indices[19] = 13;
			this.indices[20] = 14;
			this.indices[21] = 12;
			this.indices[22] = 14;
			this.indices[23] = 15;

			this.indices[24] = 16;
			this.indices[25] = 17;
			this.indices[26] = 18;
			this.indices[27] = 16;
			this.indices[28] = 18;
			this.indices[29] = 19;

			this.indices[30] = 20;
			this.indices[31] = 21;
			this.indices[32] = 22;
			this.indices[33] = 20;
			this.indices[34] = 22;
			this.indices[35] = 23;
		}

		private void BuildUV()
		{
			this.vertices[0].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[1].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[2].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[3].TextureCoordinate = new Vector2(1.0f, 0.0f);
			this.vertices[4].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[5].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[6].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[7].TextureCoordinate = new Vector2(1.0f, 0.0f);
			this.vertices[8].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[9].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[10].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[11].TextureCoordinate = new Vector2(1.0f, 0.0f);
			this.vertices[12].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[13].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[14].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[15].TextureCoordinate = new Vector2(1.0f, 0.0f);
			this.vertices[16].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[17].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[18].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[19].TextureCoordinate = new Vector2(1.0f, 0.0f);
			this.vertices[20].TextureCoordinate = new Vector2(0.0f, 0.0f);
			this.vertices[21].TextureCoordinate = new Vector2(0.0f, 1.0f);
			this.vertices[22].TextureCoordinate = new Vector2(1.0f, 1.0f);
			this.vertices[23].TextureCoordinate = new Vector2(1.0f, 0.0f);
		}

		public void  Update(GameTime gameTime, float distanceTravelled)
		{
			for (int i = 0; i <= vertices.GetUpperBound(0); i++)
			{
			    Matrix transform = Matrix.CreateTranslation(0.0f, 0.0f, distanceTravelled);
			    vertices[i].Position = Vector3.Transform(vertices[i].Position, transform);
			}
		}

		public void Draw(GraphicsDeviceManager Device, Matrix World, Matrix View, Matrix Projection, float FarClip, Effect effect)
		{
			effect.Parameters["World"].SetValue(World);
			effect.Parameters["View"].SetValue(View);
			effect.Parameters["Projection"].SetValue(Projection);
			effect.Parameters["Color"].SetValue(this.colour);
			effect.Parameters["TunnelTexture"].SetValue(Celerity.Content.ImageLibrary.TunnelTexture);
			effect.Parameters["FarClip"].SetValue(FarClip);
			effect.CurrentTechnique = effect.Techniques["Tunnel"];

			RasterizerState rasterizerState1 = new RasterizerState()
			{
				CullMode = CullMode.None,
				MultiSampleAntiAlias = false,
				FillMode = FillMode.Solid
			};
			DepthStencilState depthState = new DepthStencilState()
			{
				DepthBufferEnable = true
			};
			Device.GraphicsDevice.RasterizerState = rasterizerState1;
			Device.GraphicsDevice.DepthStencilState = depthState;
			foreach (EffectPass pass in effect.CurrentTechnique.Passes)
			{
				pass.Apply();
				Device.GraphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
																this.vertices,
																0,
																this.vertices.Count(),
																this.indices,
																0,
																this.indices.Count() / 3);
			}

		}

	}
}
